/*
    不兼容ie版本
    完全跨域解决方案
    目标：构建规则化页面不同域名的iframe页面信息交互
*/
class Dubbo {

    constructor(isInt, sign) {
        //本地目录列表 key:func 只用于本地注册函数到远程，同时记录在本地
        this.localFuncMap = {};
        //远程目录列表 相当于注册方法列表 key:window
        this.remoteFuncMap = {};
        //自身窗口
        this.window = window;
        //顶级窗口
        this.top = window.top;
        //是否为注册中心
        this.isRegistry = (this.window == this.top);
        //消息头key
        this.HEADER_KEY = "message_header_key";
        //消息头内容
        this.HEADER_INFO = sign || "tuanche";
        //初始化
        if (isInt) {
            this.init();
        }
    }

    /**
     * 发送消息到指定窗口
     * @param type "reg|run"
     * @param meg
     * @param targetWindow
     */
    sendMeg(type, meg, targetWindow) {
        //消息加签
        let info = {};
        info[this.HEADER_KEY] = this.HEADER_INFO;
        info["meg"] = meg;
        info["type"] = type;
        targetWindow.postMessage(info, "*");
    }

    /**
     * 向顶级注册函数
     * @param funcKey 函数key
     * @param origin 选填
     */
    regRemoteFunc(funcKey, func) {
        this.localFuncMap[funcKey] = func;
        //如果是注册中心注册函数 那么不再发送远程注册。
        if (this.isRegistry) {
            this.remoteFuncMap[funcKey] = this.window;
        } else {
            this.sendMeg("reg", funcKey, this.top);
        }
    }

    /**
     * 执行注册函数
     * @param funcKey 函数key
     * @param origin 选填
     */
    runRemoteFunc(funcKey, agrs, origin) {
        this.sendMeg("run", { "funcKey": funcKey, "agrs": agrs }, this.top);
    }


    //初始化
    init() {
        let thiz = this;
        let backFunc = function (e) {
            //console.log(e);
            let data = e.data;
            //进行信息验证
            if (typeof data == "object"
                && thiz.HEADER_KEY in data
                && data[thiz.HEADER_KEY] == thiz.HEADER_INFO) {
                //判断是不是注册中心
                if (thiz.isRegistry) {
                    if (data["type"] == "run" && data["meg"]["funcKey"] in thiz.remoteFuncMap) {
                        let meg = data["meg"];
                        let targetWin = thiz.remoteFuncMap[meg["funcKey"]];
                        //目标window为顶级window则直接执行
                        if (targetWin == thiz.window) {
                            thiz.localFuncMap[meg["funcKey"]](meg["agrs"]);
                        } else {
                            thiz.sendMeg("run", meg, targetWin);
                        }
                    }
                    if (data["type"] == "reg") {
                        let funcKey = data["meg"];
                        console.log("收到函数注册key:" + funcKey + "|窗口:" + e.source);
                        thiz.remoteFuncMap[funcKey] = e.source;
                    }
                } else {
                    //非注册中心 就执行目标函数
                    if (data["type"] == "run" && data["meg"]["funcKey"] in thiz.localFuncMap) {
                        let meg = data["meg"];
                        thiz.localFuncMap[meg["funcKey"]](meg["agrs"]);
                    }
                }
            }
        }

        if (this.window.addEventListener) {
            this.window.addEventListener('message', backFunc, false);
        } else if (window.attachEvent) {
            window.attachEvent("onmessage", backFunc);
        }

    }
}